﻿namespace UnityEditor
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using UnityEditorInternal;
    using UnityEngine;

    [CustomEditor(typeof(BlendTree))]
    internal class BlendTreeInspector : Editor
    {
        internal static Action<BlendTree> blendTreeHierarchyChanged;
        internal static Animator currentAnimator;
        internal static AnimatorController currentController;
        private AnimValueManager m_Anims = new AnimValueManager();
        private readonly int m_BlendAnimationID = "BlendAnimationIDHash".GetHashCode();
        private SerializedProperty m_BlendEvent;
        private BlendTree m_BlendTree;
        private SerializedProperty m_Childs;
        private readonly int m_ClickDragFloatID = "ClickDragFloatIDHash".GetHashCode();
        private bool m_HierarchyChanged;
        private SerializedProperty m_MaxThreshold;
        private SerializedProperty m_MinThreshold;
        private SerializedProperty m_Name;
        private string m_PrevBlendValueName = string.Empty;
        private ReorderableList m_ReorderableList;
        private AnimBool m_ShowAdjust = new AnimBool();
        private AnimBool m_ShowCompute = new AnimBool();
        private AnimBool m_ShowGraph = new AnimBool();
        private bool m_ShowGraphValue;
        private SerializedProperty m_UseAutomaticThresholds;
        internal static BlendTree parentBlendTree;
        private PreviewBlendTree previewBlendTree;
        private static float s_ClickDragFloatDistance;
        private static bool s_ClickDragFloatDragged;
        private static Styles styles;

        private void AddBlendTreeCallback()
        {
            BlendTree objectToAdd = new BlendTree {
                hideFlags = HideFlags.HideInHierarchy,
                name = "Blend Tree"
            };
            if (currentController != null)
            {
                objectToAdd.SetBlendEvent(currentController.GetDefaultBlendTreeEvent());
            }
            AssetDatabase.AddObjectToAsset(objectToAdd, this.m_BlendTree);
            this.SetNewThreshold(this.m_BlendTree.AddMotion(objectToAdd));
            this.m_ReorderableList.index = this.m_Childs.arraySize - 1;
            this.m_HierarchyChanged = true;
        }

        public void AddButton(Rect rect, ReorderableList list)
        {
            GenericMenu menu = new GenericMenu();
            menu.AddItem(new GUIContent("Add Motion Field"), false, new GenericMenu.MenuFunction(this.AddChildAnimation));
            menu.AddItem(EditorGUIUtility.TempContent("New Blend Tree"), false, new GenericMenu.MenuFunction(this.AddBlendTreeCallback));
            menu.Popup(rect, 0);
        }

        private void AddChildAnimation()
        {
            this.SetNewThreshold(this.m_BlendTree.AddMotion(null));
            this.m_ReorderableList.index = this.m_Childs.arraySize - 1;
            this.m_HierarchyChanged = true;
        }

        private bool AllMotions()
        {
            bool flag = true;
            for (int i = 0; (i < this.m_Childs.arraySize) && flag; i++)
            {
                flag = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Motion").objectReferenceValue is AnimationClip;
            }
            return flag;
        }

        private void AutoCompute()
        {
            Rect rect = EditorGUILayout.GetControlRect(false, 20f, EditorStyles.label, new GUILayoutOption[0]);
            Rect position = new Rect(rect.x, rect.y, 135f, 18f);
            Rect rect3 = new Rect(position.x + position.width, position.y, rect.width - position.width, 18f);
            GUI.Label(position, EditorGUIUtility.TempContent("Automate Thresholds"), EditorStyles.label);
            this.m_UseAutomaticThresholds.boolValue = EditorGUI.Toggle(rect3, this.m_UseAutomaticThresholds.boolValue);
            this.m_ShowAdjust.target = this.AllMotions();
            this.m_ShowCompute.target = !this.m_UseAutomaticThresholds.boolValue;
            if (EditorGUILayout.BeginFadeGroup(this.m_ShowCompute.faded))
            {
                rect = EditorGUILayout.GetControlRect(false, 20f, EditorStyles.label, new GUILayoutOption[0]);
                position = new Rect(rect.x, rect.y, 135f, 18f);
                rect3 = new Rect(position.x + position.width, position.y, rect.width - position.width, 18f);
                GUI.Label(position, EditorGUIUtility.TempContent("Compute Thresholds"), EditorStyles.label);
                this.ThresholdsFromAverageSpeed(rect3);
                this.ThresholdsFromAngularSpeed(rect3);
            }
            EditorGUILayout.EndFadeGroup();
            if (EditorGUILayout.BeginFadeGroup(this.m_ShowAdjust.faded))
            {
                rect = EditorGUILayout.GetControlRect(false, 20f, EditorStyles.label, new GUILayoutOption[0]);
                position = new Rect(rect.x, rect.y, 135f, 18f);
                rect3 = new Rect(position.x + position.width, position.y, rect.width - position.width, 18f);
                GUI.Label(position, EditorGUIUtility.TempContent("Adjust Time Scale"), EditorStyles.label);
                this.TimeScaleFromSpeed(rect3);
            }
            EditorGUILayout.EndFadeGroup();
        }

        public float ClickDragFloat(Rect position, float value)
        {
            return this.ClickDragFloat(position, value, false);
        }

        public float ClickDragFloat(Rect position, float value, bool alignRight)
        {
            bool flag;
            string str2;
            string allowedletters = "inftynaeINFTYNAE0123456789.,-";
            int id = EditorGUI.GetControlID(this.m_ClickDragFloatID, FocusType.Keyboard, position);
            Event current = Event.current;
            switch (current.type)
            {
                case EventType.MouseDown:
                    if ((GUIUtility.hotControl == id) || !position.Contains(current.mousePosition))
                    {
                        if (GUIUtility.hotControl == id)
                        {
                            current.Use();
                            GUIUtility.keyboardControl = id;
                        }
                        break;
                    }
                    current.Use();
                    s_ClickDragFloatDragged = false;
                    s_ClickDragFloatDistance = 0f;
                    GUIUtility.hotControl = id;
                    if (GUIUtility.keyboardControl != id)
                    {
                        EditorGUI.EndEditingActiveTextField();
                        GUIUtility.keyboardControl = 0;
                    }
                    break;

                case EventType.MouseUp:
                    if (GUIUtility.hotControl == id)
                    {
                        current.Use();
                        if ((position.Contains(current.mousePosition) && (GUIUtility.keyboardControl != id)) && !s_ClickDragFloatDragged)
                        {
                            EditorGUI.EndEditingActiveTextField();
                            GUIUtility.keyboardControl = id;
                        }
                        else if (!position.Contains(current.mousePosition))
                        {
                            GUIUtility.keyboardControl = 0;
                            GUIUtility.hotControl = 0;
                            s_ClickDragFloatDragged = false;
                        }
                        break;
                    }
                    break;

                case EventType.MouseDrag:
                    if ((GUIUtility.hotControl == id) && (GUIUtility.keyboardControl == 0))
                    {
                        s_ClickDragFloatDistance += Mathf.Abs(HandleUtility.niceMouseDelta);
                        if (s_ClickDragFloatDistance >= 5f)
                        {
                            s_ClickDragFloatDragged = true;
                            value += HandleUtility.niceMouseDelta * 0.03f;
                            value = MathUtils.RoundBasedOnMinimumDifference(value, 0.03f);
                            GUI.changed = true;
                        }
                        current.Use();
                        break;
                    }
                    break;
            }
            GUIStyle style = (GUIUtility.keyboardControl != id) ? EditorStyles.miniLabel : EditorStyles.miniTextField;
            style.alignment = !alignRight ? TextAnchor.MiddleLeft : TextAnchor.MiddleRight;
            if (GUIUtility.keyboardControl == id)
            {
                if (!EditorGUI.s_RecycledEditor.IsEditingControl(id))
                {
                    str2 = EditorGUI.s_RecycledCurrentEditingString = value.ToString("g7");
                }
                else
                {
                    str2 = EditorGUI.s_RecycledCurrentEditingString;
                    if ((current.type == EventType.ValidateCommand) && (current.commandName == "UndoRedoPerformed"))
                    {
                        str2 = value.ToString("g7");
                    }
                }
                str2 = EditorGUI.DoTextField(EditorGUI.s_RecycledEditor, id, position, str2, style, allowedletters, out flag, false, false, false);
                if (flag)
                {
                    GUI.changed = true;
                    EditorGUI.s_RecycledCurrentEditingString = str2;
                    switch (str2.ToLower())
                    {
                        case "inf":
                        case "infinity":
                            value = float.PositiveInfinity;
                            return value;

                        case "-inf":
                        case "-infinity":
                            value = float.NegativeInfinity;
                            return value;
                    }
                    if (!float.TryParse(str2.Replace(',', '.'), NumberStyles.Float, (IFormatProvider) CultureInfo.InvariantCulture.NumberFormat, out value))
                    {
                        value = EditorGUI.s_RecycledCurrentEditingFloat = 0f;
                        return value;
                    }
                    if (float.IsNaN(value))
                    {
                        value = 0f;
                    }
                    EditorGUI.s_RecycledCurrentEditingFloat = value;
                }
                return value;
            }
            str2 = value.ToString("g7");
            str2 = EditorGUI.DoTextField(EditorGUI.s_RecycledEditor, id, position, str2, style, allowedletters, out flag, false, false, false);
            return value;
        }

        public void DoHierarchyChangedCallback()
        {
            if (this.m_HierarchyChanged && (blendTreeHierarchyChanged != null))
            {
                blendTreeHierarchyChanged(this.m_BlendTree);
            }
            this.m_HierarchyChanged = false;
        }

        private void DrawAnimation(float val, float min, float max, bool selected, Rect area)
        {
            float y = area.y;
            Rect position = new Rect(min, y, val - min, area.height);
            Rect rect2 = new Rect(val, y, max - val, area.height);
            styles.triangleLeft.Draw(position, selected, selected, false, false);
            styles.triangleRight.Draw(rect2, selected, selected, false, false);
            area.height--;
            Color color = Handles.color;
            Color color2 = !selected ? new Color(1f, 1f, 1f, 0.4f) : new Color(1f, 1f, 1f, 0.6f);
            Handles.color = color2;
            Handles.DrawLine(new Vector3(val, y, 0f), new Vector3(val, y + area.height, 0f));
            Vector3[] points = new Vector3[] { new Vector3(min, y + area.height, 0f), new Vector3(val, y, 0f) };
            Handles.DrawAAPolyLine(points);
            points = new Vector3[] { new Vector3(val, y, 0f), new Vector3(max, y + area.height, 0f) };
            Handles.DrawAAPolyLine(points);
            Handles.color = color;
        }

        public void DrawChild(Rect r, int index, bool isActive, bool isFocused)
        {
            SerializedProperty arrayElementAtIndex = this.m_Childs.GetArrayElementAtIndex(index);
            SerializedProperty property = arrayElementAtIndex.FindPropertyRelative("m_Motion");
            SerializedProperty property3 = arrayElementAtIndex.FindPropertyRelative("m_Threshold");
            r.width += 8f;
            Rect position = new Rect(r.x, r.y + 1f, r.width / 2f, 16f);
            float width = !(property.objectReferenceValue is AnimationClip) ? -8f : ((r.width / 4f) - 16f);
            float num2 = ((r.width / 2f) - width) - 24f;
            Rect rect2 = new Rect((position.x + position.width) + 8f, r.y + 1f, num2, 16f);
            Rect rect3 = new Rect((rect2.x + rect2.width) + 8f, r.y + 1f, width, 16f);
            EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
            EditorGUI.BeginChangeCheck();
            Motion motion = this.m_BlendTree.GetMotion(index);
            EditorGUI.PropertyField(position, property, GUIContent.none);
            if (EditorGUI.EndChangeCheck())
            {
                if ((motion is BlendTree) && (motion != (property.objectReferenceValue as Motion)))
                {
                    if (EditorUtility.DisplayDialog("Changing BlendTree will delete previous BlendTree", "You cannot undo this action.", "Delete", "Cancel"))
                    {
                        MecanimUtilities.DestroyBlendTreeRecursive(motion as BlendTree);
                    }
                    else
                    {
                        property.objectReferenceValue = motion;
                    }
                }
                this.m_HierarchyChanged = true;
            }
            if (this.m_UseAutomaticThresholds.boolValue)
            {
                GUI.enabled = false;
            }
            float floatValue = property3.floatValue;
            EditorGUI.BeginChangeCheck();
            string s = EditorGUI.DelayedTextField(rect2, floatValue.ToString(), "inftynaeINFTYNAE0123456789.,-", EditorStyles.textField);
            if (EditorGUI.EndChangeCheck() && float.TryParse(s, NumberStyles.Float, (IFormatProvider) CultureInfo.InvariantCulture.NumberFormat, out floatValue))
            {
                property3.floatValue = floatValue;
                base.serializedObject.ApplyModifiedProperties();
                this.m_BlendTree.SortChildren();
                this.SetMinMaxThresholds();
                GUI.changed = true;
            }
            if (this.m_UseAutomaticThresholds.boolValue)
            {
                GUI.enabled = true;
            }
            if (property.objectReferenceValue is AnimationClip)
            {
                SerializedProperty property4 = arrayElementAtIndex.FindPropertyRelative("m_TimeScale");
                EditorGUI.PropertyField(rect3, property4, GUIContent.none);
            }
            EditorGUILayout.EndHorizontal();
        }

        private void DrawHeader(Rect headerRect)
        {
            headerRect.xMin += 14f;
            headerRect.width += 8f;
            Rect position = new Rect(headerRect.x - 14f, headerRect.y + 1f, (headerRect.width + 14f) / 2f, 16f);
            Rect rect2 = new Rect(position.xMax + 16f, headerRect.y + 1f, headerRect.width / 4f, 16f);
            Rect rect3 = new Rect(rect2.x + rect2.width, headerRect.y + 1f, headerRect.width / 4f, 16f);
            bool flag = true;
            for (int i = 0; (i < this.m_Childs.arraySize) && flag; i++)
            {
                flag = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Motion").objectReferenceValue is BlendTree;
            }
            GUI.Label(position, EditorGUIUtility.TempContent("Motion"), EditorStyles.label);
            if (this.m_Childs.arraySize >= 1)
            {
                GUI.Label(rect2, EditorGUIUtility.TempContent("Threshold"), EditorStyles.label);
                if (!flag)
                {
                    GUI.Label(rect3, styles.speedIcon, EditorStyles.label);
                }
            }
        }

        private void DrawTreesAndAnimations(Rect area)
        {
            area.x += 4f;
            area.width -= 8f;
            int controlID = GUIUtility.GetControlID(this.m_BlendAnimationID, FocusType.Passive);
            int arraySize = this.m_Childs.arraySize;
            float[] values = new float[arraySize];
            for (int i = 0; i < arraySize; i++)
            {
                SerializedProperty property2 = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Threshold");
                values[i] = property2.floatValue;
            }
            float from = Mathf.Min(values);
            float to = Mathf.Max(values);
            for (int j = 0; j < values.Length; j++)
            {
                values[j] = area.x + (Mathf.InverseLerp(from, to, values[j]) * area.width);
            }
            string blendEvent = this.m_BlendTree.GetBlendEvent();
            float num7 = area.x + (Mathf.InverseLerp(from, to, this.m_BlendTree.GetInputBlendValue(blendEvent)) * area.width);
            Rect position = new Rect(num7 - 4f, area.y, 9f, 42f);
            Event current = Event.current;
            switch (current.GetTypeForControl(controlID))
            {
                case EventType.MouseDown:
                {
                    if (!position.Contains(current.mousePosition))
                    {
                        if (area.Contains(current.mousePosition))
                        {
                            current.Use();
                            GUIUtility.hotControl = controlID;
                            GUIUtility.keyboardControl = controlID;
                            float x = current.mousePosition.x;
                            float positiveInfinity = float.PositiveInfinity;
                            for (int k = 0; k < values.Length; k++)
                            {
                                float num15 = (k != 0) ? values[k - 1] : values[k];
                                float num16 = (k != (values.Length - 1)) ? values[k + 1] : values[k];
                                if (((Mathf.Abs((float) (x - values[k])) < positiveInfinity) && (x < num16)) && (x > num15))
                                {
                                    positiveInfinity = Mathf.Abs((float) (x - values[k]));
                                    this.m_ReorderableList.index = k;
                                }
                            }
                            this.m_UseAutomaticThresholds.boolValue = false;
                        }
                        break;
                    }
                    current.Use();
                    GUIUtility.hotControl = controlID;
                    this.m_ReorderableList.index = -1;
                    this.m_ReorderableList.index = -1;
                    float t = Mathf.InverseLerp(0f, area.width, current.mousePosition.x - 4f);
                    t = Mathf.Lerp(from, to, t);
                    this.m_BlendTree.SetInputBlendValue(blendEvent, t);
                    if (parentBlendTree != null)
                    {
                        parentBlendTree.SetInputBlendValue(blendEvent, t);
                    }
                    break;
                }
                case EventType.MouseUp:
                    if (GUIUtility.hotControl == controlID)
                    {
                        current.Use();
                        GUIUtility.hotControl = 0;
                        this.m_ReorderableList.index = -1;
                    }
                    break;

                case EventType.MouseDrag:
                    if (GUIUtility.hotControl == controlID)
                    {
                        current.Use();
                        if (this.m_ReorderableList.index == -1)
                        {
                            float num17 = Mathf.InverseLerp(0f, area.width, current.mousePosition.x - 4f);
                            num17 = Mathf.Lerp(from, to, num17);
                            this.m_BlendTree.SetInputBlendValue(blendEvent, num17);
                            if (parentBlendTree != null)
                            {
                                parentBlendTree.SetInputBlendValue(blendEvent, num17);
                            }
                        }
                        else
                        {
                            float num18 = Mathf.InverseLerp(0f, area.width, current.mousePosition.x);
                            num18 = Mathf.Lerp(from, to, num18);
                            SerializedProperty arrayElementAtIndex = this.m_Childs.GetArrayElementAtIndex(this.m_ReorderableList.index);
                            SerializedProperty property4 = arrayElementAtIndex.FindPropertyRelative("m_Threshold");
                            SerializedProperty property5 = (this.m_ReorderableList.index > 0) ? this.m_Childs.GetArrayElementAtIndex(this.m_ReorderableList.index - 1) : arrayElementAtIndex;
                            SerializedProperty property6 = (this.m_ReorderableList.index != (this.m_Childs.arraySize - 1)) ? this.m_Childs.GetArrayElementAtIndex(this.m_ReorderableList.index + 1) : arrayElementAtIndex;
                            SerializedProperty property7 = property5.FindPropertyRelative("m_Threshold");
                            SerializedProperty property8 = property6.FindPropertyRelative("m_Threshold");
                            float num19 = (to - from) / area.width;
                            float num20 = current.delta.x;
                            property4.floatValue += num20 * num19;
                            if ((property4.floatValue < property7.floatValue) && (this.m_ReorderableList.index != 0))
                            {
                                this.m_Childs.MoveArrayElement(this.m_ReorderableList.index, this.m_ReorderableList.index - 1);
                                this.m_ReorderableList.index--;
                            }
                            if ((property4.floatValue > property8.floatValue) && (this.m_ReorderableList.index < (this.m_Childs.arraySize - 1)))
                            {
                                this.m_Childs.MoveArrayElement(this.m_ReorderableList.index, this.m_ReorderableList.index + 1);
                                this.m_ReorderableList.index++;
                            }
                            float num21 = 3f * ((to - from) / area.width);
                            if ((property4.floatValue - property7.floatValue) <= num21)
                            {
                                property4.floatValue = property7.floatValue;
                            }
                            else if ((property8.floatValue - property4.floatValue) <= num21)
                            {
                                property4.floatValue = property8.floatValue;
                            }
                        }
                        break;
                    }
                    break;

                case EventType.Repaint:
                {
                    styles.background.Draw(area, GUIContent.none, false, false, false, false);
                    if (this.m_Childs.arraySize < 2)
                    {
                        GUI.Label(area, EditorGUIUtility.TempContent("Please Add Motion Fields or Blend Trees"), styles.errorStyle);
                        break;
                    }
                    for (int m = 0; m < values.Length; m++)
                    {
                        float min = (m != 0) ? values[m - 1] : values[m];
                        float max = (m != (values.Length - 1)) ? values[m + 1] : values[m];
                        bool selected = this.m_ReorderableList.index == m;
                        this.DrawAnimation(values[m], min, max, selected, area);
                    }
                    Color color = Handles.color;
                    Handles.color = new Color(0f, 0f, 0f, 0.25f);
                    Handles.DrawLine(new Vector3(area.x, area.y + area.height, 0f), new Vector3(area.x + area.width, area.y + area.height, 0f));
                    Handles.color = color;
                    styles.blendPosition.Draw(position, GUIContent.none, false, false, false, false);
                    break;
                }
            }
        }

        public void EndDragChild(ReorderableList list)
        {
            List<float> list2 = new List<float>();
            for (int i = 0; i < this.m_Childs.arraySize; i++)
            {
                SerializedProperty property2 = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Threshold");
                list2.Add(property2.floatValue);
            }
            list2.Sort();
            for (int j = 0; j < this.m_Childs.arraySize; j++)
            {
                this.m_Childs.GetArrayElementAtIndex(j).FindPropertyRelative("m_Threshold").floatValue = list2[j];
            }
            base.serializedObject.ApplyModifiedProperties();
            this.m_HierarchyChanged = true;
        }

        public override bool HasPreviewGUI()
        {
            return ((this.previewBlendTree != null) && this.previewBlendTree.HasPreviewGUI());
        }

        private void Init()
        {
            if (styles == null)
            {
                styles = new Styles();
            }
            if (this.m_BlendTree == null)
            {
                this.m_BlendTree = base.target as BlendTree;
            }
            if (styles == null)
            {
                styles = new Styles();
            }
            if (this.previewBlendTree == null)
            {
                this.previewBlendTree = new PreviewBlendTree();
            }
            if (this.m_Childs == null)
            {
                this.m_Childs = base.serializedObject.FindProperty("m_Childs");
                this.m_ReorderableList = new ReorderableList(base.serializedObject, this.m_Childs);
                this.m_ReorderableList.drawHeaderCallback = new ReorderableList.HeaderCallbackDelegate(this.DrawHeader);
                this.m_ReorderableList.drawElementCallback = new ReorderableList.ElementCallbackDelegate(this.DrawChild);
                this.m_ReorderableList.onReorderCallback = new ReorderableList.ReorderCallbackDelegate(this.EndDragChild);
                this.m_ReorderableList.onAddDropdownCallback = new ReorderableList.AddDropdownCallbackDelegate(this.AddButton);
                this.m_ReorderableList.onRemoveCallback = new ReorderableList.RemoveCallbackDelegate(this.RemoveButton);
                this.SortByThreshold();
                this.m_ShowGraphValue = this.m_Childs.arraySize >= 2;
                this.m_ShowGraph.value = this.m_ShowGraphValue;
                this.m_ShowAdjust.value = this.AllMotions();
                this.m_ShowCompute.value = !this.m_UseAutomaticThresholds.boolValue;
                this.m_Anims.Add(this.m_ShowGraph);
                this.m_Anims.Add(this.m_ShowAdjust);
                this.m_Anims.Add(this.m_ShowCompute);
            }
            this.previewBlendTree.Init(this.m_BlendTree);
        }

        public void OnDestroy()
        {
            if (this.previewBlendTree != null)
            {
                this.previewBlendTree.OnDestroy();
            }
        }

        public void OnDisable()
        {
            if (this.previewBlendTree != null)
            {
                this.previewBlendTree.OnDisable();
            }
        }

        public void OnEnable()
        {
            this.m_Name = base.serializedObject.FindProperty("m_Name");
            this.m_BlendEvent = base.serializedObject.FindProperty("m_BlendEvent");
            this.m_UseAutomaticThresholds = base.serializedObject.FindProperty("m_UseAutomaticThresholds");
            this.m_MinThreshold = base.serializedObject.FindProperty("m_MinThreshold");
            this.m_MaxThreshold = base.serializedObject.FindProperty("m_MaxThreshold");
        }

        internal override void OnHeaderIconGUI(Rect iconRect)
        {
            Texture2D miniThumbnail = AssetPreview.GetMiniThumbnail(base.target);
            GUI.Label(iconRect, miniThumbnail);
        }

        internal override void OnHeaderTitleGUI(Rect titleRect, string header)
        {
            base.serializedObject.Update();
            Rect position = titleRect;
            position.height = 16f;
            EditorGUI.BeginChangeCheck();
            EditorGUI.showMixedValue = this.m_Name.hasMultipleDifferentValues;
            string str = EditorGUI.DelayedTextField(position, this.m_Name.stringValue, null, EditorStyles.textField);
            EditorGUI.showMixedValue = false;
            if (EditorGUI.EndChangeCheck() && !string.IsNullOrEmpty(str))
            {
                foreach (UnityEngine.Object obj2 in base.targets)
                {
                    ObjectNames.SetNameSmart(obj2, str);
                }
                this.m_HierarchyChanged = true;
            }
            if (this.m_BlendTree != null)
            {
                position.y += 18f;
                GUI.Label(position, EditorGUIUtility.TempContent("Parameter"));
                position.x += 65f;
                position.width -= 65f;
                List<string> list = new List<string>();
                if (currentController == null)
                {
                    EditorGUI.PropertyField(position, this.m_BlendEvent, EditorGUIUtility.TempContent("Blend Parameter"));
                    return;
                }
                string blendEvent = this.m_BlendTree.GetBlendEvent();
                int selectedIndex = 0;
                for (int i = 0; i < currentController.GetEventCount(); i++)
                {
                    if (currentController.GetEventType(i) == 1)
                    {
                        string eventName = currentController.GetEventName(i);
                        selectedIndex = !(eventName == blendEvent) ? selectedIndex : list.Count;
                        list.Add(eventName);
                    }
                }
                int num4 = EditorGUI.Popup(position, selectedIndex, list.ToArray());
                if (num4 != selectedIndex)
                {
                    this.m_BlendEvent.stringValue = list[num4];
                }
                if (this.m_PrevBlendValueName != blendEvent)
                {
                    this.m_PrevBlendValueName = blendEvent;
                    this.previewBlendTree.ResetStateMachine();
                }
            }
            base.serializedObject.ApplyModifiedProperties();
        }

        public override void OnInspectorGUI()
        {
            this.Init();
            if (this.m_Anims.callback == null)
            {
                this.m_Anims.callback = new AnimValueManager.Callback(this.Repaint);
            }
            base.serializedObject.Update();
            this.m_ShowGraphValue = this.m_Childs.arraySize >= 2;
            this.m_ShowGraph.target = this.m_ShowGraphValue;
            this.m_UseAutomaticThresholds = base.serializedObject.FindProperty("m_UseAutomaticThresholds");
            GUI.enabled = true;
            EditorGUIUtility.LookLikeControls();
            if (EditorGUILayout.BeginFadeGroup(this.m_ShowGraph.faded))
            {
                this.DrawTreesAndAnimations(EditorGUILayout.GetControlRect(false, 40f, styles.background, new GUILayoutOption[0]));
                this.ThresholdValues();
                GUILayout.Space(5f);
            }
            EditorGUILayout.EndFadeGroup();
            if (this.m_ReorderableList != null)
            {
                this.m_ReorderableList.DoList();
            }
            if (this.m_ShowGraphValue)
            {
                GUILayout.Space(10f);
                this.AutoCompute();
            }
            EditorGUIUtility.LookLikeInspector();
            base.serializedObject.ApplyModifiedProperties();
            this.DoHierarchyChangedCallback();
        }

        public override void OnInteractivePreviewGUI(Rect r, GUIStyle background)
        {
            if (this.previewBlendTree != null)
            {
                this.previewBlendTree.OnInteractivePreviewGUI(r, background);
            }
        }

        public override void OnPreviewSettings()
        {
            if (this.previewBlendTree != null)
            {
                this.previewBlendTree.OnPreviewSettings();
            }
        }

        public void RemoveButton(ReorderableList list)
        {
            this.m_Childs.DeleteArrayElementAtIndex(list.index);
            if (list.index >= this.m_Childs.arraySize)
            {
                list.index = this.m_Childs.arraySize - 1;
            }
            this.SetMinMaxThresholds();
            this.m_HierarchyChanged = true;
        }

        private void SetMinMaxThreshold()
        {
            base.m_SerializedObject.Update();
            SerializedProperty property = this.m_Childs.GetArrayElementAtIndex(0).FindPropertyRelative("m_Threshold");
            SerializedProperty property2 = this.m_Childs.GetArrayElementAtIndex(this.m_Childs.arraySize - 1).FindPropertyRelative("m_Threshold");
            this.m_MinThreshold.floatValue = Mathf.Min(property.floatValue, property2.floatValue);
            this.m_MaxThreshold.floatValue = Mathf.Max(property.floatValue, property2.floatValue);
            base.m_SerializedObject.ApplyModifiedProperties();
        }

        private void SetMinMaxThresholds()
        {
            float positiveInfinity = float.PositiveInfinity;
            float negativeInfinity = float.NegativeInfinity;
            for (int i = 0; i < this.m_Childs.arraySize; i++)
            {
                SerializedProperty property2 = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Threshold");
                positiveInfinity = (property2.floatValue >= positiveInfinity) ? positiveInfinity : property2.floatValue;
                negativeInfinity = (property2.floatValue <= negativeInfinity) ? negativeInfinity : property2.floatValue;
            }
            this.m_MinThreshold.floatValue = (this.m_Childs.arraySize <= 0) ? 0f : positiveInfinity;
            this.m_MaxThreshold.floatValue = (this.m_Childs.arraySize <= 0) ? 1f : negativeInfinity;
        }

        private void SetNewThreshold(int index)
        {
            if (!this.m_UseAutomaticThresholds.boolValue)
            {
                base.serializedObject.Update();
                float num = 0f;
                if ((this.m_Childs.arraySize >= 3) && (index == (this.m_Childs.arraySize - 1)))
                {
                    float floatValue = this.m_Childs.GetArrayElementAtIndex(index - 2).FindPropertyRelative("m_Threshold").floatValue;
                    float num3 = this.m_Childs.GetArrayElementAtIndex(index - 1).FindPropertyRelative("m_Threshold").floatValue;
                    num = num3 + (num3 - floatValue);
                }
                else if (this.m_Childs.arraySize == 1)
                {
                    num = 0f;
                }
                else
                {
                    num = this.m_Childs.GetArrayElementAtIndex(this.m_Childs.arraySize - 1).FindPropertyRelative("m_Threshold").floatValue + 1f;
                }
                this.m_Childs.GetArrayElementAtIndex(index).FindPropertyRelative("m_Threshold").floatValue = num;
                this.SetMinMaxThresholds();
                base.serializedObject.ApplyModifiedProperties();
            }
        }

        private void SortByThreshold()
        {
            base.m_SerializedObject.Update();
            for (int i = 0; i < this.m_Childs.arraySize; i++)
            {
                float positiveInfinity = float.PositiveInfinity;
                int srcIndex = -1;
                for (int j = i; j < this.m_Childs.arraySize; j++)
                {
                    float floatValue = this.m_Childs.GetArrayElementAtIndex(j).FindPropertyRelative("m_Threshold").floatValue;
                    if (floatValue < positiveInfinity)
                    {
                        positiveInfinity = floatValue;
                        srcIndex = j;
                    }
                }
                this.m_Childs.MoveArrayElement(srcIndex, i);
            }
            base.m_SerializedObject.ApplyModifiedProperties();
            this.m_HierarchyChanged = true;
        }

        private void ThresholdsFromAngularSpeed(Rect controlRect)
        {
            controlRect.x += Mathf.Floor(controlRect.width / 2f);
            controlRect.width = Mathf.Ceil(controlRect.width / 2f);
            if (GUI.Button(controlRect, new GUIContent("Angular", "Compute Thresholds from Angular Speeds"), "ButtonRight"))
            {
                this.m_UseAutomaticThresholds.boolValue = false;
                for (int i = 0; i < this.m_Childs.arraySize; i++)
                {
                    SerializedProperty property = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Motion");
                    SerializedProperty property2 = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Threshold");
                    Motion objectReferenceValue = property.objectReferenceValue as Motion;
                    if (objectReferenceValue != null)
                    {
                        property2.floatValue = (objectReferenceValue.averageAngularSpeed * 180f) / 3.141593f;
                    }
                }
                base.m_SerializedObject.ApplyModifiedProperties();
                this.SortByThreshold();
                this.SetMinMaxThreshold();
            }
        }

        private void ThresholdsFromAverageSpeed(Rect controlRect)
        {
            controlRect.width = Mathf.Floor(controlRect.width / 2f);
            if (GUI.Button(controlRect, new GUIContent("Average", "Compute Thresholds from Average Speed"), "ButtonLeft"))
            {
                this.m_UseAutomaticThresholds.boolValue = false;
                for (int i = 0; i < this.m_Childs.arraySize; i++)
                {
                    SerializedProperty property = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Motion");
                    SerializedProperty property2 = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Threshold");
                    Motion objectReferenceValue = property.objectReferenceValue as Motion;
                    if (objectReferenceValue != null)
                    {
                        property2.floatValue = objectReferenceValue.apparentSpeed;
                    }
                }
                base.m_SerializedObject.ApplyModifiedProperties();
                this.SortByThreshold();
                this.SetMinMaxThreshold();
            }
        }

        private void ThresholdValues()
        {
            Rect controlRect = EditorGUILayout.GetControlRect(new GUILayoutOption[0]);
            Rect position = controlRect;
            Rect rect3 = controlRect;
            position.width /= 4f;
            rect3.width /= 4f;
            rect3.x = (controlRect.x + controlRect.width) - rect3.width;
            float floatValue = this.m_MinThreshold.floatValue;
            float num2 = this.m_MaxThreshold.floatValue;
            EditorGUI.BeginChangeCheck();
            floatValue = this.ClickDragFloat(position, floatValue);
            num2 = this.ClickDragFloat(rect3, num2, true);
            if (EditorGUI.EndChangeCheck())
            {
                if (this.m_Childs.arraySize >= 2)
                {
                    SerializedProperty arrayElementAtIndex = this.m_Childs.GetArrayElementAtIndex(0);
                    SerializedProperty property2 = this.m_Childs.GetArrayElementAtIndex(this.m_Childs.arraySize - 1);
                    SerializedProperty property3 = arrayElementAtIndex.FindPropertyRelative("m_Threshold");
                    SerializedProperty property4 = property2.FindPropertyRelative("m_Threshold");
                    property3.floatValue = Mathf.Min(floatValue, num2);
                    property4.floatValue = Mathf.Max(floatValue, num2);
                }
                if (!this.m_UseAutomaticThresholds.boolValue)
                {
                    for (int i = 0; i < this.m_Childs.arraySize; i++)
                    {
                        SerializedProperty property6 = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Threshold");
                        float t = Mathf.InverseLerp(this.m_MinThreshold.floatValue, this.m_MaxThreshold.floatValue, property6.floatValue);
                        property6.floatValue = Mathf.Lerp(Mathf.Min(floatValue, num2), Mathf.Max(floatValue, num2), t);
                    }
                }
                this.m_MinThreshold.floatValue = Mathf.Min(floatValue, num2);
                this.m_MaxThreshold.floatValue = Mathf.Max(floatValue, num2);
            }
        }

        private void TimeScaleFromSpeed(Rect controlRect)
        {
            if (GUI.Button(controlRect, new GUIContent("Homogenized", "Adjust Time Scale for Homogeneous Speed")))
            {
                float apparentSpeed = this.m_BlendTree.apparentSpeed;
                for (int i = 0; i < this.m_Childs.arraySize; i++)
                {
                    AnimationClip objectReferenceValue = this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_Motion").objectReferenceValue as AnimationClip;
                    if (objectReferenceValue != null)
                    {
                        if (objectReferenceValue.isAnimatorMotion)
                        {
                            this.m_Childs.GetArrayElementAtIndex(i).FindPropertyRelative("m_TimeScale").floatValue = apparentSpeed / objectReferenceValue.apparentSpeed;
                        }
                        else
                        {
                            Debug.LogWarning("Could not adjust time scale for " + objectReferenceValue.name + " because it is not a muscle clip");
                        }
                    }
                }
            }
        }

        private class PreviewBlendTree
        {
            private AvatarPreview m_AvatarPreview;
            private BlendTree m_BlendTree;
            private AnimatorController m_Controller;
            private bool m_PrevIKOnFeet;
            private UnityEditorInternal.State m_State;
            private StateMachine m_StateMachine;

            private void ClearStateMachine()
            {
                if ((this.m_AvatarPreview != null) && (this.m_AvatarPreview.Animator != null))
                {
                    AnimatorController.SetAnimatorController(this.m_AvatarPreview.Animator, null);
                }
                UnityEngine.Object.DestroyImmediate(this.m_Controller);
                UnityEngine.Object.DestroyImmediate(this.m_StateMachine);
                UnityEngine.Object.DestroyImmediate(this.m_State);
                this.m_StateMachine = null;
                this.m_Controller = null;
                this.m_State = null;
            }

            public void CreateEvents()
            {
                int eventCount = this.m_Controller.GetEventCount();
                for (int i = 0; i < eventCount; i++)
                {
                    this.m_Controller.RemoveEvent(0);
                }
                for (int j = 0; j < this.m_BlendTree.GetRecursiveBlendEventCount(); j++)
                {
                    this.m_Controller.AddEvent(this.m_BlendTree.GetRecursiveBlendEvent(j), AnimatorControllerEventType.Float);
                }
            }

            private void CreateStateMachine()
            {
                if ((this.m_AvatarPreview != null) && (this.m_AvatarPreview.Animator != null))
                {
                    if (this.m_StateMachine == null)
                    {
                        this.m_StateMachine = new StateMachine();
                        this.m_StateMachine.hideFlags = HideFlags.DontSave;
                    }
                    if (this.m_State == null)
                    {
                        this.m_State = this.m_StateMachine.AddState("preview");
                        this.m_State.SetMotion(0, this.m_BlendTree);
                        this.m_State.SetIKOnFeet(this.m_AvatarPreview.IKOnFeet);
                        this.m_State.hideFlags = HideFlags.DontSave;
                    }
                    if (this.m_Controller == null)
                    {
                        this.m_Controller = new AnimatorController();
                        this.m_Controller.AddLayer("preview");
                        this.m_Controller.SetLayerStateMachine(0, this.m_StateMachine);
                        this.CreateEvents();
                        AnimatorController.SetAnimatorController(this.m_AvatarPreview.Animator, this.m_Controller);
                        this.m_Controller.hideFlags = HideFlags.DontSave;
                    }
                    if (AnimatorController.GetAnimatorController(this.m_AvatarPreview.Animator) != this.m_Controller)
                    {
                        AnimatorController.SetAnimatorController(this.m_AvatarPreview.Animator, this.m_Controller);
                    }
                }
            }

            public bool HasPreviewGUI()
            {
                return true;
            }

            public void Init(BlendTree blendTree)
            {
                this.m_BlendTree = blendTree;
                if (this.m_AvatarPreview == null)
                {
                    this.m_AvatarPreview = new AvatarPreview(BlendTreeInspector.currentAnimator, this.m_BlendTree);
                    this.m_AvatarPreview.OnAvatarChangeFunc = new AvatarPreview.OnAvatarChange(this.OnPreviewAvatarChanged);
                    this.m_PrevIKOnFeet = this.m_AvatarPreview.IKOnFeet;
                }
                this.CreateStateMachine();
            }

            public void OnDestroy()
            {
                this.ClearStateMachine();
                if (this.m_AvatarPreview != null)
                {
                    this.m_AvatarPreview.OnDestroy();
                    this.m_AvatarPreview = null;
                }
            }

            public void OnDisable()
            {
                this.ClearStateMachine();
                this.m_AvatarPreview.OnDestroy();
            }

            public void OnInteractivePreviewGUI(Rect r, GUIStyle background)
            {
                this.UpdateAvatarState();
                this.m_AvatarPreview.DoAvatarPreview(r, background);
            }

            private void OnPreviewAvatarChanged()
            {
                this.ResetStateMachine();
            }

            public void OnPreviewSettings()
            {
                this.m_AvatarPreview.DoPreviewSettings();
            }

            public void ResetStateMachine()
            {
                this.ClearStateMachine();
                this.CreateStateMachine();
            }

            public void TestForReset()
            {
                if (((this.m_State != null) && (this.m_AvatarPreview != null)) && (this.m_State.GetIKOnFeet() != this.m_AvatarPreview.IKOnFeet))
                {
                    this.ResetStateMachine();
                }
            }

            private void UpdateAvatarState()
            {
                Animator animator = this.m_AvatarPreview.Animator;
                if (animator != null)
                {
                    if (this.m_PrevIKOnFeet != this.m_AvatarPreview.IKOnFeet)
                    {
                        this.m_PrevIKOnFeet = this.m_AvatarPreview.IKOnFeet;
                        Vector3 rootPosition = this.m_AvatarPreview.Animator.rootPosition;
                        Quaternion rootRotation = this.m_AvatarPreview.Animator.rootRotation;
                        this.ResetStateMachine();
                        this.m_AvatarPreview.Animator.Update(this.m_AvatarPreview.timeControl.currentTime);
                        this.m_AvatarPreview.Animator.Update(0f);
                        this.m_AvatarPreview.Animator.rootPosition = rootPosition;
                        this.m_AvatarPreview.Animator.rootRotation = rootRotation;
                    }
                    if (animator != null)
                    {
                        for (int i = 0; i < this.m_BlendTree.GetRecursiveBlendEventCount(); i++)
                        {
                            string recursiveBlendEvent = this.m_BlendTree.GetRecursiveBlendEvent(i);
                            float inputBlendValue = this.m_BlendTree.GetInputBlendValue(recursiveBlendEvent);
                            animator.SetFloat(recursiveBlendEvent, inputBlendValue);
                        }
                    }
                    this.m_AvatarPreview.timeControl.loop = true;
                    float length = 1f;
                    float normalizedTime = 0f;
                    if (animator.layerCount > 0)
                    {
                        AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
                        length = currentAnimatorStateInfo.length;
                        normalizedTime = currentAnimatorStateInfo.normalizedTime;
                    }
                    this.m_AvatarPreview.timeControl.startTime = 0f;
                    this.m_AvatarPreview.timeControl.stopTime = length;
                    this.m_AvatarPreview.timeControl.Update();
                    float deltaTime = this.m_AvatarPreview.timeControl.deltaTime;
                    if (!this.m_BlendTree.isLooping)
                    {
                        if (normalizedTime >= 1f)
                        {
                            deltaTime -= length;
                        }
                        else if (normalizedTime < 0f)
                        {
                            deltaTime += length;
                        }
                    }
                    animator.Update(deltaTime);
                }
            }
        }

        private class Styles
        {
            public readonly GUIStyle background = "MeBlendBackground";
            public readonly GUIStyle blendPosition = "MeBlendPosition";
            public GUIStyle errorStyle = new GUIStyle(EditorStyles.label);
            public GUIContent speedIcon = new GUIContent(EditorGUIUtility.IconContent("SpeedScale"));
            public readonly GUIStyle triangleLeft = "MeBlendTriangleLeft";
            public readonly GUIStyle triangleRight = "MeBlendTriangleRight";

            public Styles()
            {
                this.errorStyle.alignment = TextAnchor.MiddleCenter;
                this.speedIcon.tooltip = "Changes animation speed";
            }
        }
    }
}

